﻿/*******************************************************************************

  NLocalizer (C) 2010-2012 Chris Prusik (KAP1 Ltd www.kap1.net)
  The fast, simple solution for localizing .NET applications, by text files.
  Latest version: http://NLocalizer.codeplex.com/

  $Id$

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

*******************************************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.IO;
using Microsoft.CSharp;
using System.Threading;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.Reflection;
using System.Globalization;
using System.Xml;
using NLocalizer;

namespace NLocalizerApp
{
    public partial class MainForm : Form
    {
        private Assembly translationAssembly = null;
        private CompilerResults translationCompiler = null;
        private int compileCounter = 0;
        private Translation translation = new Translation();
        private bool edited = false;
        private DataTable table = new DataTable();
        private DataColumn staticColumn = new DataColumn("Static", typeof(bool));
        private DataColumn classColumn = new DataColumn("Class", typeof(string));
        private DataColumn propertyColumn = new DataColumn("Property", typeof(string));

        public MainForm()
        {
            InitializeComponent();
            BindingSource bs = new BindingSource(table, "");
            TranslationGrid.DataSource = bs;
            table.Columns.Add(classColumn);
            table.Columns.Add(propertyColumn);
            table.Columns.Add(staticColumn);
            table.PrimaryKey = new DataColumn[] { classColumn, propertyColumn };
            TranslationGrid.Columns[classColumn.ColumnName].DefaultCellStyle.BackColor = Color.AntiqueWhite;
            TranslationGrid.Columns[classColumn.ColumnName].Width = 80;
            TranslationGrid.Columns[propertyColumn.ColumnName].DefaultCellStyle.BackColor = Color.AntiqueWhite;
            TranslationGrid.Columns[propertyColumn.ColumnName].Width = 160;
            TranslationGrid.Columns[staticColumn.ColumnName].DefaultCellStyle.BackColor = Color.AntiqueWhite;
            TranslationGrid.Columns[staticColumn.ColumnName].Width = 40;
            FillTable();
            EditedStatusLabel.Text = "Empty";
            classColumn.ReadOnly = true;
            propertyColumn.ReadOnly = true;
            Text = String.Format("NLocalizerApp {0} (C) Chris Prusik (KAP1 Ltd www.kap1.net), NLocalizer.CodePlex.com",
                Application.ProductVersion.ToString());
        }

        private Type CompileAndGetType()
        {
            translationCompiler = RuntimeCompiler.Compile(translation,
                Path.GetDirectoryName(OpenFileDialog.FileName), translationAssembly);
            if (translationCompiler == null)
                MessageBox.Show("Unnable to compile", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            if (translationCompiler.Errors.Count > 0)
            {
                string errors = "Compile error:\r\n";
                for(int i = 0; i < translationCompiler.Errors.Count; i++)
                    errors += translationCompiler.Errors[i].ErrorText;
            }
            Type type = RuntimeCompiler.GetCompiledClass(translationCompiler);
            compileCounter++;
            return type;
        }

        private void FillTable()
        {
            foreach (KeyValuePair<string, TranslationClasses> item in translation)
                if (table.Columns.Contains(item.Key) == false)
                {
                    DataColumn tableColumn = table.Columns.Add(item.Key, typeof(string));
                    DataGridViewColumn gridColumn = TranslationGrid.Columns[tableColumn.ColumnName];
                    if (gridColumn != null)
                        gridColumn.Width = 200;
                }

            List<string> toRemove = new List<string>();
            foreach (DataColumn item in table.Columns)
                if (item.ColumnName != staticColumn.ColumnName &&
                    item.ColumnName != classColumn.ColumnName &&
                    item.ColumnName != propertyColumn.ColumnName &&
                    translation.Exists(item.Caption) == false)
                    toRemove.Add(item.ColumnName);
            foreach(string columnName in toRemove)
                table.Columns.Remove(columnName);

            if (TranslationGrid.Columns["Neutral"] != null)
            {
                TranslationGrid.Columns["Neutral"].ReadOnly = true;
                TranslationGrid.Columns["Neutral"].DefaultCellStyle.BackColor = Color.LightGray;
            }

            table.Rows.Clear();
            if (translation.Exists(translation.GetEnglishName()))
                foreach (KeyValuePair<string, TranslationProperties> cl in translation[translation.GetEnglishName()])
                    foreach (KeyValuePair<string, TranslationProperty> prop in cl.Value)
                    {
                        bool found = SearchTextBox.Text == "" || 
                            Regex.IsMatch(cl.Key, SearchTextBox.Text, RegexOptions.IgnoreCase) ||
                            Regex.IsMatch(prop.Key, SearchTextBox.Text, RegexOptions.IgnoreCase);
                        if (found == false)
                            foreach(KeyValuePair<string, TranslationClasses> lang in translation)
                                if (Regex.IsMatch(translation.GetProperty(lang.Key, cl.Key, prop.Key).Message,
                                    SearchTextBox.Text, RegexOptions.IgnoreCase))
                                    found = true;
                        if (found)
                        {
                            DataRow row = table.Rows.Find(new object[] { cl.Key, prop.Key });
                            if (row == null)
                                row = table.Rows.Add(cl.Key, prop.Key);
                            row.BeginEdit();
                            foreach (KeyValuePair<string, TranslationClasses> lang in translation)
                                if (translation.Exists(lang.Key, cl.Key, prop.Key))
                                {
                                    row[lang.Key] = LangWriter.ReplaceSpecialChars(
                                        translation.GetProperty(lang.Key, cl.Key, prop.Key).Message);
                                    row[staticColumn.ColumnName] = translation.GetProperty(lang.Key, cl.Key, prop.Key).IsStatic;
                                }
                                else
                                {
                                    row[lang.Key] = LangWriter.ReplaceSpecialChars("***" + translation.GetProperty(lang.Key, cl.Key, prop.Key).Message);
                                    row[staticColumn.ColumnName] = translation.GetProperty(lang.Key, cl.Key, prop.Key).IsStatic;
                                }
                            row.AcceptChanges();
                        }
                    }
        }

        private void FillClasses()
        {
            ClassDropDownButton.DropDownItems.Clear();
            if (translation.Exists(translation.GetEnglishName()))
                foreach (KeyValuePair<string, TranslationProperties> item in translation[translation.GetEnglishName()])
                    ClassDropDownButton.DropDownItems.Add(item.Key);
        }

        private void NewButton_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are You sure to create new translation project?\r\nAll old .lang files will be deleted", 
                "Confirmation", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK &&
                OpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    foreach (string fileName in Directory.GetFiles(
                        Path.GetDirectoryName(OpenFileDialog.FileName), "*.lang", SearchOption.AllDirectories))
                        File.Delete(fileName);
                    translation.Clear();
                    FillClasses();
                    FillTable();
                    FileNameLabel.Text = Path.GetFileName(OpenFileDialog.FileName);
                    InfoStatusLabel.Text = "New translation procect created.";
                    ImportFileDialog.InitialDirectory = Path.GetDirectoryName(OpenFileDialog.FileName);
                    edited = false;
                    EditedStatusLabel.Text = "Saved";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        private void OpenButton_Click(object sender, EventArgs e)
        {
            if (OpenFileDialog.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    // TODO: Load Assembly and Show form
                    //AppDomain.CurrentDomain.Load(OpenFileDialog.FileName);
                    translation.Clear();
                    translation.Read(Translator.GetTranslationDirectory(OpenFileDialog.FileName));
                    FillClasses();
                    FillTable();
                    FileNameLabel.Text = Path.GetFileName(OpenFileDialog.FileName);
                    InfoStatusLabel.Text = "Language files opened";
                    ImportFileDialog.InitialDirectory = Path.GetDirectoryName(OpenFileDialog.FileName);
                    edited = false;
                    EditedStatusLabel.Text = "Saved";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }

            }
        }

        private void SaveButton_Click(object sender, EventArgs e)
        {
            if (File.Exists(OpenFileDialog.FileName))
                try
                {
                    translation.Write(Translator.GetTranslationDirectory(OpenFileDialog.FileName));
                    InfoStatusLabel.Text = "Language files saved";
                    edited = false;
                    EditedStatusLabel.Text = "Saved";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            else
                MessageBox.Show("Open file first", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        private void SearchButton_Click(object sender, EventArgs e)
        {
            FillTable();
            InfoStatusLabel.Text = "Found " + TranslationGrid.Rows.Count.ToString() + " rows";
        }

        private void ClassDropDownButton_DropDownItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            SearchTextBox.Text = e.ClickedItem.Text;
            SearchButton_Click(sender, e);
        }

        private void SearchTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
                SearchButton_Click(sender, e);
        }

        private void ImportButton_Click(object sender, EventArgs e)
        {
            if (File.Exists(OpenFileDialog.FileName))
            {
                if (ImportFileDialog.ShowDialog() == DialogResult.OK)
                {
                    using (ImportForm form = new ImportForm())
                    {
                        form.Text = "Import project: " + Path.GetFileName(ImportFileDialog.FileName);
                        XmlDocument xml = new XmlDocument();
                        xml.Load(ImportFileDialog.FileName);
                        foreach (XmlNode group in xml.DocumentElement.ChildNodes)
                            if (group.Name == "ItemGroup")
                                foreach (XmlNode node in group.ChildNodes)
                                    if (node.Name == "Compile" && node.Attributes["Include"] != null)
                                    {
                                        string fileName = Path.Combine(
                                            Path.GetDirectoryName(ImportFileDialog.FileName),
                                            node.Attributes["Include"].InnerText);
                                        if (fileName.EndsWith("Designer.cs") && (fileName.IndexOf(@"\Properties\") < 0))
                                            form.FilesListBox.Items.Add(fileName, true);
                                        else if (fileName.EndsWith("Designer.vb") && (fileName.IndexOf(@"\My Project\") < 0))
                                            form.FilesListBox.Items.Add(fileName, true);
                                        else if (fileName.IndexOf("Messages") >= 0)
                                            form.FilesListBox.Items.Add(fileName, true);
                                        else if (fileName.IndexOf(@"\Properties\") < 0)
                                            form.FilesListBox.Items.Add(fileName, false);
                                    }
                        form.Translation = translation;
                        form.ShowDialog();
                        FillClasses();
                        FillTable();
                        InfoStatusLabel.Text = "Source files imported";
                    }
                }
            }
            else
                MessageBox.Show("Open file first", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        private void TranslationGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                string languageName = TranslationGrid.Columns[e.ColumnIndex].HeaderText;
                string formName = (string)TranslationGrid.Rows[e.RowIndex].Cells[classColumn.ColumnName].Value;
                string propertyName = (string)TranslationGrid.Rows[e.RowIndex].Cells[propertyColumn.ColumnName].Value;
                bool staticName = (bool)TranslationGrid.Rows[e.RowIndex].Cells[staticColumn.ColumnName].Value;
                string value = (string)TranslationGrid.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
                if (translation.GetProperty(languageName, formName, propertyName).Message != value)
                {
                    translation.SetProperty(languageName, formName, propertyName, value, staticName);
                    edited = true;
                    EditedStatusLabel.Text = "Not saved";
                }
            }
            catch
            {
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (edited &&
                MessageBox.Show("There are not saved, edited messages.\r\nAre You sure to close application?",
                    "Confirmation", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question) != DialogResult.Yes)
                e.Cancel = true;
        }

        private void ShowAllButton_Click(object sender, EventArgs e)
        {
            SearchTextBox.Text = "";
            SearchButton_Click(sender, e);
        }

        private void HomePageButton_Click(object sender, EventArgs e)
        {
            try
            {
                Process.Start("http://nlocalizer.codeplex.com");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void ShowProgress(int value, int maxValue)
        {
            if (StatusProgress.Maximum != maxValue)
                StatusProgress.Maximum = maxValue;
            InfoStatusLabel.Text = String.Format("Translating... {0} of {1}", value, maxValue);
            StatusProgress.Value = value;
            Application.DoEvents();
        }

        private void SetLocalesListBox(ListBox listBox)
        {
            foreach (CultureInfo cultureInfo in CultureInfo.GetCultures(CultureTypes.AllCultures))
            {
                string[] name = cultureInfo.Name.Split('-');
                if (name.Length == 1 && name[0] != "")
                    listBox.Items.Add(cultureInfo.Name + " / " +
                        cultureInfo.EnglishName + " / " +
                        cultureInfo.DisplayName + " / " +
                        cultureInfo.NativeName);
            }
        }

        private int FindLanguage(ComboBox comboBox, string language)
        {
            if (language.Trim() == "")
                return -1;

            for (int index = 0; index < comboBox.Items.Count; index++)
            {
                string[] items = comboBox.Items[index].ToString().Split('/');
                if (String.Compare(items[1].Trim(), language.Trim(), true) == 0)
                    return index;
            }

            return -1;
        }

        private void SetTranslateFrom(ComboBox comboBox)
        {
            foreach (KeyValuePair<string, TranslationClasses> pair in translation)
                foreach (string item in translation.Locales.GetLocales(pair.Key))
                {
                    string[] items = item.Split('-');
                    if (items.Length == 1)
                        comboBox.Items.Add(items[0] + " / " + pair.Key);
                }

            if (TranslationGrid.CurrentCell != null &&
                TranslationGrid.CurrentCell.OwningColumn != null)
                comboBox.SelectedIndex = FindLanguage(comboBox, TranslationGrid.CurrentCell.OwningColumn.HeaderText);
            if (comboBox.SelectedIndex == -1)
                comboBox.SelectedIndex = FindLanguage(comboBox, translation.GetEnglishName());
        }

        private void AddLanguageButton_Click(object sender, EventArgs e)
        {
            if (File.Exists(OpenFileDialog.FileName))
            {
                using (AddLangForm form = new AddLangForm())
                {
                    SetLocalesListBox(form.LocalesListBox);
                    SetTranslateFrom(form.TranslateFromCombo);

                    if (form.ShowDialog() == DialogResult.OK)
                    {
                        string[] items = form.LocalesListBox.Items[form.LocalesListBox.SelectedIndex].ToString().Split('/');
                        if (items.Length > 2)
                        {
                            if (translation.ContainsKey(items[1]))
                                MessageBox.Show(String.Format("Translation {0} already exists", items[1]),
                                    "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                            else
                            {
                                Cursor = Cursors.WaitCursor;
                                ToolStrip.Enabled = false;
                                TranslationGrid.Enabled = false;
                                try
                                {
                                    translation.Add(items[1].Trim(), form.AutoTranslateCheck.Checked, 
                                        form.TranslateFromCombo.Text.Split('/')[1].Trim(), ShowProgress);
                                    FillClasses();
                                    FillTable();
                                    InfoStatusLabel.Text = "Language " + items[1].Trim() + " added";
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                }
                                finally
                                {
                                    ToolStrip.Enabled = true;
                                    TranslationGrid.Enabled = true;
                                    Cursor = Cursors.Default;
                                    StatusProgress.Value = 0;
                                }
                            }
                        }
                    }
                }
            }
            else
                MessageBox.Show("Open file first", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        private bool editTextChanging = false;

        private void TranslationGrid_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
            if (TranslationGrid.CurrentCell != null &&
                TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != classColumn.ColumnName &&
                TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != propertyColumn.ColumnName &&
                TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != staticColumn.ColumnName)
            {
                editTextChanging = true;
                EditText.Text = LangReader.ReplaceSpecialChars(TranslationGrid.CurrentCell.Value.ToString());
                editTextChanging = false;
                EditText.Enabled =
                    TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != "Neutral";
            }
            else
            {
                EditText.Text = "";
                EditText.Enabled = false;
            }
        }

        private void EditText_TextChanged(object sender, EventArgs e)
        {
            if (editTextChanging == false &&
                TranslationGrid.CurrentCell != null &&
                TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != classColumn.ColumnName &&
                TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != propertyColumn.ColumnName &&
                TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != staticColumn.ColumnName &&
                TranslationGrid.CurrentCell.OwningColumn.DataPropertyName != "Neutral")
            {
                TranslationGrid.CurrentCell.Value = LangWriter.ReplaceSpecialChars(EditText.Text);
                TranslationGrid_CellEndEdit(this, 
                    new DataGridViewCellEventArgs(TranslationGrid.CurrentCell.ColumnIndex,
                        TranslationGrid.CurrentCell.RowIndex));
            }
        }

        private void ShowButton_Click(object sender, EventArgs e)
        {
            if (File.Exists(OpenFileDialog.FileName))
                try
                {
                    Process.Start(OpenFileDialog.FileName);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            else
                MessageBox.Show("Open file first", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Warning);
        }

        private void ContextCutMenu_Click(object sender, EventArgs e)
        {
            ContextCutMenu_Click(sender, e);
            ContextClearMenu_Click(sender, e);
        }

        private void ContextCopyMenu_Click(object sender, EventArgs e)
        {
            if (TranslationGrid.SelectedCells.Count > 0)
                try
                {
                    Clipboard.SetDataObject(TranslationGrid.GetClipboardContent());
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
        }

        private void ContextPasteMenu_Click(object sender, EventArgs e)
        {
            if (TranslationGrid.SelectedCells.Count > 0)
                try
                {
                    string text = Clipboard.GetText(TextDataFormat.UnicodeText);
                    string[] rows = text.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);

                    int topRowIndex = int.MaxValue;
                    int leftCellIndex = int.MaxValue;
                    foreach (DataGridViewCell cell in TranslationGrid.SelectedCells)
                    {
                        topRowIndex = Math.Min(topRowIndex, cell.RowIndex);
                        leftCellIndex = Math.Min(leftCellIndex, cell.ColumnIndex);
                    }

                    int rowIndex = 0;
                    while (rowIndex < rows.Length)
                    {
                        string[] cells = rows[rowIndex].Split('\t');
                        int iCol = 0;
                        while (iCol < cells.Length)
                        {
                            if (TranslationGrid.ColumnCount - 1 >= leftCellIndex + iCol)
                            {
                                DataGridViewCell cell = TranslationGrid.Rows[topRowIndex + rowIndex].Cells[leftCellIndex + iCol];
                                if (cell.OwningColumn.ReadOnly == false && cell.ColumnIndex > 2)
                                {
                                    cell.Value = cells[iCol];
                                    translation.SetProperty(cell.OwningColumn.HeaderText,
                                        TranslationGrid.Rows[cell.RowIndex].Cells[0].Value.ToString(),
                                        TranslationGrid.Rows[cell.RowIndex].Cells[1].Value.ToString(),
                                        cell.Value.ToString(),
                                        (bool)TranslationGrid.Rows[cell.RowIndex].Cells[2].Value);
                                }
                            }
                            iCol++;
                        }
                        rowIndex++;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
        }

        private void ContextClearMenu_Click(object sender, EventArgs e)
        {
            foreach (DataGridViewCell cell in TranslationGrid.SelectedCells)
                if (cell.OwningColumn.ReadOnly == false && cell.ColumnIndex > 2)
                {
                    cell.Value = null;
                    translation.SetProperty(cell.OwningColumn.HeaderText,
                        TranslationGrid.Rows[cell.RowIndex].Cells[0].Value.ToString(),
                        TranslationGrid.Rows[cell.RowIndex].Cells[1].Value.ToString(),
                        cell.Value.ToString(),
                        (bool)TranslationGrid.Rows[cell.RowIndex].Cells[2].Value);
                }
        }

        private void ContextAddLangMenu_Click(object sender, EventArgs e)
        {
            AddLanguageButton_Click(sender, e);
        }

        private void ContextTranslateMenu_Click(object sender, EventArgs e)
        {
            if (TranslationGrid.SelectedCells.Count > 0)
                using (TranslateForm form = new TranslateForm())
                {
                    SetTranslateFrom(form.FromLanguageCombo);
                    form.FromLanguageCombo.SelectedIndex = FindLanguage(
                        form.FromLanguageCombo, translation.GetEnglishName());
                    form.ItemsLabel.Text = String.Format("{0} items to translate",
                        TranslationGrid.SelectedCells.Count);
                    if (form.ShowDialog() == DialogResult.OK)
                        try
                        {
                            ToolStrip.Enabled = false;
                            TranslationGrid.Enabled = false;
                            Cursor = Cursors.WaitCursor;
                            int ommited = 0;
                            int errors = 0;
                            string fromLanguage = form.FromLanguageCombo.Text.Split('/')[1].Trim();
                            CultureInfo fromCulture = translation.FindCultureInfo(fromLanguage);
                            if (fromCulture != null)
                            {
                                for (int index = 0; index < TranslationGrid.SelectedCells.Count; index++)
                                {
                                    DataGridViewCell cell = TranslationGrid.SelectedCells[index];
                                    string fromText = translation.GetProperty(fromLanguage,
                                        TranslationGrid.Rows[cell.RowIndex].Cells[0].Value.ToString(),
                                        TranslationGrid.Rows[cell.RowIndex].Cells[1].Value.ToString()).Message;
                                    CultureInfo toCulture = translation.FindCultureInfo(cell.OwningColumn.HeaderText);
                                    if (toCulture != null && 
                                        toCulture.EnglishName != fromCulture.EnglishName &&
                                        fromText.Trim() != "")
                                    {
                                        try
                                        {
                                            cell.Value = GoogleTranslator.Translate(fromText, fromCulture.EnglishName, toCulture.EnglishName);
                                        }
                                        catch
                                        {
                                            cell.Value = "Translating error";
                                            errors++;
                                        }
                                        translation.SetProperty(cell.OwningColumn.HeaderText,
                                            TranslationGrid.Rows[cell.RowIndex].Cells[0].Value.ToString(),
                                            TranslationGrid.Rows[cell.RowIndex].Cells[1].Value.ToString(),
                                            cell.Value.ToString(),
                                            (bool)TranslationGrid.Rows[cell.RowIndex].Cells[2].Value);
                                        ShowProgress(index, TranslationGrid.SelectedCells.Count);
                                    }
                                    else
                                        ommited++;
                                }
                            }
                            InfoStatusLabel.Text = String.Format("Translated {0} items ({1} ommited, {2} errors)", 
                                TranslationGrid.SelectedCells.Count - ommited - errors, ommited, errors);
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }
                        finally
                        {
                            ToolStrip.Enabled = true;
                            TranslationGrid.Enabled = true;
                            Cursor = Cursors.Default;
                            StatusProgress.Value = 0;
                        }
                }
        }
    }
}